Transit Gateway Flow LogsをAthenaで分析してみた

Transit Gateway Flow LogsをAthenaで分析してみた

Clock Icon2022.10.26

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Transit Gateway Flow LogsもAthenaで分析してみたい

こんにちは、のんピ(@non____97)です。

皆さんはTransit Gateway Flow LogsもAthenaで分析してみたいなと思ったことはありますか? 私はあります。

以下AWS公式ドキュメントにはVPC Flow Logsに対してAthenaで分析をする際のDDLやクエリの例が記載されています。

一方、Transit Gateway Flow Logsはリリースされてから3ヶ月程度しか経っていないこともあり、AWS公式ドキュメントにAthenaで分析をする例は記載されていません。

ないなら自分でやるしかないですね。

やってみたので紹介します。

検証環境

検証環境は以下の通りです。

Transit Gateway Flow Logs検証環境構成図

VPC間をTransit Gatewayで接続しておきます。そしてEC2インスタンス間で適当な通信を行い、出力されたログをAthenaで分析します。

Transit Gateway Flow Logsの設定

それではTransit Gateway Flow Logsの設定をします。

Transit Gateway Flow Logs以外のリソースはAWS CDKでデプロイします。

使用したコードは以下リポジトリに保存しています。

AWS CDKで各リソースデプロイ後、Transit Gateway Flow Logsの設定を行います。

作成したTransit Gatewayを選択して、フローログタブからフローログ作成をクリックします。

フローログを作成

フローログの設定を行います。せっかくS3バケットに出力してAthenaで分析をするのでログファイルの形式はParquetで、Hive互換S3プレフィックスを有効化します。また、Transit Gateway Flow LogsはVPC Flow Logsと異なり、長期間のログ分析というよりも、スポットでのトラブルシューティング時に参照するイメージがあるため1時間ごとにパーティションを切るように設定しました。

Transit Gateway Flow Logsの設定

フローログを作成をクリックして、Transit Gateway Flow Logsが設定されたことを確認します。

Transit_Gateway_Flow_Logsの確認

AWS CLIからもTransit Gateway Flow Logsの設定を確認しておきます。

$ aws ec2 describe-flow-logs
{
    "FlowLogs": [
        {
            "CreationTime": "2022-10-25T23:44:03.755000+00:00",
            "DeliverLogsStatus": "SUCCESS",
            "FlowLogId": "fl-04e097231ef9f0be8",
            "FlowLogStatus": "ACTIVE",
            "ResourceId": "tgw-02da28fb6055d6390",
            "LogDestinationType": "s3",
            "LogDestination": "arn:aws:s3:::bucket-tgw-flow-logs-query-test",
            "LogFormat": "${version} ${resource-type} ${account-id} ${tgw-id} ${tgw-attachment-id} ${tgw-src-vpc-account-id} ${tgw-dst-vpc-account-id} ${tgw-src-vpc-id} ${tgw-dst-vpc-id} ${tgw-src-subnet-id} ${tgw-dst-subnet-id} ${tgw-src-eni} ${tgw-dst-eni} ${tgw-src-az-id} ${tgw-dst-az-id} ${tgw-pair-attachment-id} ${srcaddr} ${dstaddr} ${srcport} ${dstport} ${protocol} ${packets} ${bytes} ${start} ${end} ${log-status} ${type} ${packets-lost-no-route} ${packets-lost-blackhole} ${packets-lost-mtu-exceeded} ${packets-lost-ttl-expired} ${tcp-flags} ${region} ${flow-direction} ${pkt-src-aws-service} ${pkt-dst-aws-service}",
            "Tags": [
                {
                    "Key": "Name",
                    "Value": "tgw-flow-logs"
                }
            ],
            "MaxAggregationInterval": 60,
            "DestinationOptions": {
                "FileFormat": "parquet",
                "HiveCompatiblePartitions": true,
                "PerHourPartition": true
            }
        }
    ]
}

MaxAggregationInterval60で固定なので、Parquetによる圧縮効果はそこまで見込めなさそうです。

なお、Transit Gateway Flow LogsはVPC Flow Logsと異なり、Athena統合用のCloudFormationのテンプレートは提供されていません。

Athena統合がないことを確認

動作確認として、EC2インスタンス間で適当に通信を行い、Transit Gateway Flow LogsによりTransit Gatewayを通る通信がS3バケットに出力されることを確認します。

# ICMP Echo Request 
sh-4.2$ ping ec2-18-209-158-146.compute-1.amazonaws.com
.
.
(中略)
.
.
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=950 ttl=254 time=0.507 ms
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=951 ttl=254 time=0.492 ms
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=952 ttl=254 time=0.512 ms
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=953 ttl=254 time=0.486 ms
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=954 ttl=254 time=0.730 ms
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=955 ttl=254 time=0.566 ms
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=956 ttl=254 time=0.477 ms
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=957 ttl=254 time=0.488 ms
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=958 ttl=254 time=0.528 ms
64 bytes from ip-10-0-2-4.ec2.internal (10.0.2.4): icmp_seq=959 ttl=254 time=0.453 ms
^C
--- ec2-18-209-158-146.compute-1.amazonaws.com ping statistics ---
959 packets transmitted, 959 received, 0% packet loss, time 980831ms
rtt min/avg/max/mdev = 0.415/0.498/1.049/0.065 ms

# ポートスキャン
sh-4.2$ sudo nmap -O ec2-18-209-158-146.compute-1.amazonaws.com

Starting Nmap 6.40 ( http://nmap.org ) at 2022-10-26 00:02 UTC
Nmap scan report for ec2-18-209-158-146.compute-1.amazonaws.com (10.0.2.4)
Host is up (0.00060s latency).
rDNS record for 10.0.2.4: ip-10-0-2-4.ec2.internal
Not shown: 998 closed ports
PORT    STATE SERVICE
22/tcp  open  ssh
111/tcp open  rpcbind
No exact OS matches for host (If you know what OS is running on it, see http://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=6.40%E=4%D=10/26%OT=22%CT=1%CU=39173%PV=Y%DS=2%DC=I%G=Y%TM=635879
OS:06%P=x86_64-koji-linux-gnu)SEQ(SP=103%GCD=1%ISR=10E%TI=Z%CI=Z%II=I%TS=A)
OS:OPS(O1=M210CST11NW7%O2=M210CST11NW7%O3=M210CNNT11NW7%O4=M210CST11NW7%O5=
OS:M210CST11NW7%O6=M210CST11)WIN(W1=68DF%W2=68DF%W3=68DF%W4=68DF%W5=68DF%W6
OS:=68DF)ECN(R=Y%DF=Y%T=FF%W=6903%O=M210CNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=FF%S=
OS:O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=FF%W=0%S=A%A=Z%F=R%O=%RD
OS:=0%Q=)T5(R=Y%DF=Y%T=FF%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=FF%W=0
OS:%S=A%A=Z%F=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=FF%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1
OS:(R=Y%DF=N%T=FF%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI
OS:=N%T=FF%CD=S)

Network Distance: 2 hops

OS detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.87 seconds

しばらくした後、s3-treeでS3バケットにログが出力されていることを確認します。

$ s3-tree bucket-tgw-flow-logs-query-test
bucket-tgw-flow-logs-query-test
└── AWSLogs
    └── aws-account-id=<AWSアカウントID>
        └── aws-service=vpcflowlogs
            └── aws-region=us-east-1
                └── year=2022
                    └── month=10
                        ├── day=25
                        │   └── hour=23
                        │       ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221025T2345Z_37faec00.log.parquet
                        │       ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221025T2345Z_6e64a0c3.log.parquet
                        │       ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221025T2345Z_a68deccf.log.parquet
                        │       ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221025T2350Z_8ebee505.log.parquet
                        │       ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221025T2350Z_e1c565ac.log.parquet
                        │       ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221025T2355Z_8e5c981d.log.parquet
                        │       └── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221025T2355Z_b51f8e74.log.parquet
                        └── day=26
                            └── hour=00
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0000Z_649dcfcc.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0000Z_65927196.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0000Z_7eb9802d.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0005Z_0f6f731a.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0005Z_4981a057.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0005Z_8d171d66.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0010Z_1cdda543.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0010Z_42fb4134.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0010Z_d5ab0985.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0015Z_084fb0af.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0015Z_da0ea646.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0015Z_e3820ac8.log.parquet
                                ├── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0020Z_63918803.log.parquet
                                └── <AWSアカウントID>_vpcflowlogs_us-east-1_fl-04e097231ef9f0be8_20221026T0020Z_ce8451ef.log.parquet

10 directories, 21 files

Apache Hive形式でparquetのログが出力されていますね。

Athenaのテーブルを定義

それではAthenaでクエリを投げるにあたって、テーブルを定義します。

以下のようなDDLを準備しました。

CREATE EXTERNAL TABLE `transit_gateway_flow_logs_partition_projection`(
  `version` int, 
  `resource_type` string, 
  `account_id` string, 
  `tgw_id` string, 
  `tgw_attachment_id` string, 
  `tgw_src_vpc_account_id` string, 
  `tgw_dst_vpc_account_id` string, 
  `tgw_src_vpc_id` string, 
  `tgw_dst_vpc_id` string, 
  `tgw_src_subnet_id` string, 
  `tgw_dst_subnet_id` string, 
  `tgw_src_eni` string, 
  `tgw_dst_eni` string, 
  `tgw_src_az_id` string, 
  `tgw_dst_az_id` string, 
  `tgw_pair_attachment_id` string, 
  `srcaddr` string, 
  `dstaddr` string, 
  `srcport` int, 
  `dstport` int, 
  `protocol` bigint, 
  `packets` bigint, 
  `bytes` bigint, 
  `start` bigint, 
  `end` bigint, 
  `log_status` string, 
  `type` string, 
  `packets_lost_no_route` bigint, 
  `packets_lost_blackhole` bigint, 
  `packets_lost_mtu_exceeded` bigint, 
  `packets_lost_ttl_expired` bigint, 
  `tcp_flags` int, 
  `region` string, 
  `flow_direction` string, 
  `pkt_src_aws_service` string, 
  `pkt_dst_aws_service` string
)
PARTITIONED BY (
  `aws_account_id` string,
  `aws_service` string,
  `aws_region` string,
  `year` int, 
  `month` int, 
  `day` int,
  `hour` int
)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  's3://bucket-tgw-flow-logs-query-test/AWSLogs/'
TBLPROPERTIES (
  'projection.enabled'='true', 
  'has_encrypted_data'='true', 
  'classification'='parquet',
  'projection.aws_account_id.type'='enum', 
  'projection.aws_account_id.values'='<AWSアカウントID>', 
  'projection.aws_region.type'='enum', 
  'projection.aws_region.values'='us-east-1,ap-northeast-1', 
  'projection.aws_service.type'='enum', 
  'projection.aws_service.values'='vpcflowlogs', 
  'projection.year.type'='integer', 
  'projection.year.digits'='4', 
  'projection.year.interval'='1', 
  'projection.year.range'='2021,2023', 
  'projection.month.type'='integer', 
  'projection.month.digits'='2', 
  'projection.month.interval'='1', 
  'projection.month.range'='1,12', 
  'projection.day.type'='integer', 
  'projection.day.digits'='2', 
  'projection.day.interval'='1', 
  'projection.day.range'='1,31', 
  'projection.hour.type'='integer', 
  'projection.hour.digits'='2', 
  'projection.hour.interval'='1', 
  'projection.hour.range'='0,23', 
  'storage.location.template'='s3://bucket-tgw-flow-logs-query-test/AWSLogs/aws-account-id=${aws_account_id}/aws-service=${aws_service}/aws-region=${aws_region}/year=${year}/month=${month}/day=${day}/hour=${hour}'
)

パーティションはPartition Projectionで定義しています。

Partition Projectionとは?」という方は以下記事をご覧ください。

パーティションは年月日だけではなく、リージョンやAWSアカウントなど変数として指定できる箇所全て切っています。aws_serviceはパーティション切らなくてもよかったような気がしますが、勢いで切りました。

こちらのDDLをAthenaで実行します。すると、テーブル一覧に定義したテーブルが表示されるようになります。

Athena DDL

Glueのテーブルを確認すると同様のテーブルが追加されていました。

Glueテーブルの確認

Athenaでクエリを実行

それでは、Athenaでクエリを実行を実行してみます。

まず、2022/10/25に記録されたログを10件確認してみます。

SELECT *
FROM 
  transit_gateway_flow_logs_partition_projection
WHERE
  aws_account_id='<AWSアカウントID>' and
  aws_service='vpcflowlogs' and
  aws_region='us-east-1' and
  year=2022 and 
  month=10 and
  day=25
LIMIT 10

実行結果は以下の通りです。

#	version	resource_type	account_id	tgw_id	tgw_attachment_id	tgw_src_vpc_account_id	tgw_dst_vpc_account_id	tgw_src_vpc_id	tgw_dst_vpc_id	tgw_src_subnet_id	tgw_dst_subnet_id	tgw_src_eni	tgw_dst_eni	tgw_src_az_id	tgw_dst_az_id	tgw_pair_attachment_id	srcaddr	dstaddr	srcport	dstport	protocol	packets	bytes	start	end	log_status	type	packets_lost_no_route	packets_lost_blackhole	packets_lost_mtu_exceeded	packets_lost_ttl_expired	tcp_flags	region	flow_direction	pkt_src_aws_service	pkt_dst_aws_service	aws_account_id	aws_service	aws_region	year	month	day	hour
1	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-02c9dd0bab96a55b6	<AWSアカウントID>	<AWSアカウントID>	vpc-045298e6cd2d652a2	vpc-087d43220f581376d	subnet-0691b0b8f47b7c4c4	subnet-0ee99191181dbde82	eni-08e0123c60b43d0a2	eni-067361ddd20f34899	use1-az6	use1-az6	tgw-attach-0a1f82bc5c0513a12	10.0.2.4	10.0.1.9	0	0	1	59	4956	1666741980	1666742039	OK	IPv4	0	0	0	0	0	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
2	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-045298e6cd2d652a2	vpc-087d43220f581376d	subnet-0691b0b8f47b7c4c4	subnet-0ee99191181dbde82	eni-08e0123c60b43d0a2	eni-067361ddd20f34899	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.2.4	10.0.1.9	0	0	1	59	4956	1666741980	1666742039	OK	IPv4	0	0	0	0	0	us-east-1	ingress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
3	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-02c9dd0bab96a55b6	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-0a1f82bc5c0513a12	10.0.1.9	10.0.2.4	0	0	1	59	4956	1666741980	1666742039	OK	IPv4	0	0	0	0	0	us-east-1	ingress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
4	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.1.9	10.0.2.4	0	0	1	59	4956	1666742040	1666742099	OK	IPv4	0	0	0	0	0	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
5	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-045298e6cd2d652a2	vpc-087d43220f581376d	subnet-0691b0b8f47b7c4c4	subnet-0ee99191181dbde82	eni-08e0123c60b43d0a2	eni-067361ddd20f34899	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.2.4	10.0.1.9	0	0	1	59	4956	1666742040	1666742099	OK	IPv4	0	0	0	0	0	us-east-1	ingress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
6	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-02c9dd0bab96a55b6	<AWSアカウントID>	<AWSアカウントID>	vpc-045298e6cd2d652a2	vpc-087d43220f581376d	subnet-0691b0b8f47b7c4c4	subnet-0ee99191181dbde82	eni-08e0123c60b43d0a2	eni-067361ddd20f34899	use1-az6	use1-az6	tgw-attach-0a1f82bc5c0513a12	10.0.2.4	10.0.1.9	0	0	1	58	4872	1666741500	1666741559	OK	IPv4	0	0	0	0	0	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
7	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-02c9dd0bab96a55b6	<AWSアカウントID>	<AWSアカウントID>	vpc-045298e6cd2d652a2	vpc-087d43220f581376d	subnet-0691b0b8f47b7c4c4	subnet-0ee99191181dbde82	eni-08e0123c60b43d0a2	eni-067361ddd20f34899	use1-az6	use1-az6	tgw-attach-0a1f82bc5c0513a12	10.0.2.4	10.0.1.9	0	0	1	59	4956	1666741560	1666741619	OK	IPv4	0	0	0	0	0	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
8	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.1.9	10.0.2.4	0	0	1	58	4872	1666741620	1666741679	OK	IPv4	0	0	0	0	0	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
9	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-02c9dd0bab96a55b6	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-0a1f82bc5c0513a12	10.0.1.9	10.0.2.4	0	0	1	58	4872	1666741500	1666741559	OK	IPv4	0	0	0	0	0	us-east-1	ingress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
10	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-045298e6cd2d652a2	vpc-087d43220f581376d	subnet-0691b0b8f47b7c4c4	subnet-0ee99191181dbde82	eni-08e0123c60b43d0a2	eni-067361ddd20f34899	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.2.4	10.0.1.9	0	0	1	58	4872	1666741620	1666741679	OK	IPv4	0	0	0	0	0	us-east-1	ingress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23

Athenaクエリー1

Partition Projectionを有効化しているのでMSCK REPAIR TABLEを実行してロードしなくても正しく取得できていますね。

続いて、2022/10に記録された宛先ポートが22番のログを10件出力します。

SELECT *
FROM 
  transit_gateway_flow_logs_partition_projection
WHERE
  year=2022 and 
  month=10 and
  dstport=22
LIMIT 10

実行結果は以下の通りです。

#	version	resource_type	account_id	tgw_id	tgw_attachment_id	tgw_src_vpc_account_id	tgw_dst_vpc_account_id	tgw_src_vpc_id	tgw_dst_vpc_id	tgw_src_subnet_id	tgw_dst_subnet_id	tgw_src_eni	tgw_dst_eni	tgw_src_az_id	tgw_dst_az_id	tgw_pair_attachment_id	srcaddr	dstaddr	srcport	dstport	protocol	packets	bytes	start	end	log_status	type	packets_lost_no_route	packets_lost_blackhole	packets_lost_mtu_exceeded	packets_lost_ttl_expired	tcp_flags	region	flow_direction	pkt_src_aws_service	pkt_dst_aws_service	aws_account_id	aws_service	aws_region	year	month	day	hour
1	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-02c9dd0bab96a55b6	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-0a1f82bc5c0513a12	10.0.1.9	10.0.2.4	35392	22	6	3	164	1666742370	1666742370	OK	IPv4	0	0	0	0	22	us-east-1	ingress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
2	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.1.9	10.0.2.4	35392	22	6	3	164	1666742370	1666742370	OK	IPv4	0	0	0	0	22	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	25	23
3	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-02c9dd0bab96a55b6	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-0a1f82bc5c0513a12	10.0.1.9	10.0.2.4	41653	22	17	1	28	1666742584	1666742636	OK	IPv4	0	0	0	0	0	us-east-1	ingress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	26	0
4	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-02c9dd0bab96a55b6	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-0a1f82bc5c0513a12	10.0.1.9	10.0.2.4	41654	22	17	1	28	1666742584	1666742636	OK	IPv4	0	0	0	0	0	us-east-1	ingress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	26	0
5	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.1.9	10.0.2.4	41653	22	17	1	28	1666742584	1666742630	OK	IPv4	0	0	0	0	0	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	26	0
6	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.1.9	10.0.2.4	60833	22	6	10	480	1666742523	1666742534	OK	IPv4	0	0	0	0	6	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	26	0
7	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.1.9	10.0.2.4	60830	22	6	10	500	1666742523	1666742534	OK	IPv4	0	0	0	0	6	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	26	0
8	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.1.9	10.0.2.4	59389	22	6	2	84	1666742523	1666742534	OK	IPv4	0	0	0	0	6	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	26	0
9	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.1.9	10.0.2.4	60828	22	6	10	500	1666742523	1666742534	OK	IPv4	0	0	0	0	6	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	26	0
10	6	TransitGateway	<AWSアカウントID>	tgw-02da28fb6055d6390	tgw-attach-0a1f82bc5c0513a12	<AWSアカウントID>	<AWSアカウントID>	vpc-087d43220f581376d	vpc-045298e6cd2d652a2	subnet-0ee99191181dbde82	subnet-0691b0b8f47b7c4c4	eni-067361ddd20f34899	eni-08e0123c60b43d0a2	use1-az6	use1-az6	tgw-attach-02c9dd0bab96a55b6	10.0.1.9	10.0.2.4	60829	22	6	10	500	1666742523	1666742534	OK	IPv4	0	0	0	0	6	us-east-1	egress	-	-	<AWSアカウントID>	vpcflowlogs	us-east-1	2022	10	26	0

Athenaクエリー2

自分だけの最強のDDLを作ろう

Transit Gateway Flow LogsをAthenaで分析してみました。

今回は1時間ごとにパーティションを切りましたが、より広いレンジで分析したい場合は24時間ごとでパーティションを切っても良いと思います。

ぜひ自分だけの最強のDDLを作成して、Athenaで分析してみてください。

なお、Transit Gateway Flow LogsをApache Hive形式で出力にしているため、Partition Projectionのdate型と相性が悪いです。無理矢理定義しようとチャレンジしてみましたがAthenaの裏で動いているJavaのエラーが出力されてしましました。

その時のDDLやクエリ、エラー分は以下の通りです。

  • DDL
CREATE EXTERNAL TABLE `transit_gateway_flow_logs_partition_projection_date`(
  `version` int, 
  `resource_type` string, 
  `account_id` string, 
  `tgw_id` string, 
  `tgw_attachment_id` string, 
  `tgw_src_vpc_account_id` string, 
  `tgw_dst_vpc_account_id` string, 
  `tgw_src_vpc_id` string, 
  `tgw_dst_vpc_id` string, 
  `tgw_src_subnet_id` string, 
  `tgw_dst_subnet_id` string, 
  `tgw_src_eni` string, 
  `tgw_dst_eni` string, 
  `tgw_src_az_id` string, 
  `tgw_dst_az_id` string, 
  `tgw_pair_attachment_id` string, 
  `srcaddr` string, 
  `dstaddr` string, 
  `srcport` int, 
  `dstport` int, 
  `protocol` bigint, 
  `packets` bigint, 
  `bytes` bigint, 
  `start` bigint, 
  `end` bigint, 
  `log_status` string, 
  `type` string, 
  `packets_lost_no_route` bigint, 
  `packets_lost_blackhole` bigint, 
  `packets_lost_mtu_exceeded` bigint, 
  `packets_lost_ttl_expired` bigint, 
  `tcp_flags` int, 
  `region` string, 
  `flow_direction` string, 
  `pkt_src_aws_service` string, 
  `pkt_dst_aws_service` string
)
PARTITIONED BY (
  `aws_account_id` string,
  `aws_service` string,
  `aws_region` string,
  `year` int, 
  `month` int, 
  `day` int,
  `hour` int
)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  's3://bucket-tgw-flow-logs-query-test/AWSLogs/'
TBLPROPERTIES (
  'projection.enabled'='true', 
  'has_encrypted_data'='true', 
  'classification'='parquet',
  'projection.hour.type'='date', 
  'projection.hour.range'='NOW-1YEARS,NOW', 
  'projection.hour.format'='HH', 
  'projection.hour.interval'='1', 
  'projection.hour.interval.unit'='HOURS', 
  'projection.day.type'='date', 
  'projection.day.range'='NOW-1YEARS,NOW', 
  'projection.day.format'='dd', 
  'projection.day.interval'='1', 
  'projection.day.interval.unit'='DAYS', 
  'projection.month.type'='date', 
  'projection.month.range'='NOW-1YEARS,NOW', 
  'projection.month.format'='MM', 
  'projection.month.interval'='1', 
  'projection.month.interval.unit'='MONTHS', 
  'projection.year.type'='date', 
  'projection.year.range'='NOW-1YEARS,NOW', 
  'projection.year.format'='yyyy', 
  'projection.year.interval'='1', 
  'projection.year.interval.unit'='YEARS', 
  'projection.aws_service.type'='enum', 
  'projection.aws_service.values'='vpcflowlogs', 
  'projection.aws_region.type'='enum', 
  'projection.aws_region.values'='us-east-1,ap-northeast-1', 
  'projection.aws_account_id.type'='enum', 
  'projection.aws_account_id.values'='<AWSアカウントID>', 
  'storage.location.template'='s3://bucket-tgw-flow-logs-query-test/AWSLogs/aws-account-id=${aws_account_id}/aws-service=${aws_service}/aws-region=${aws_region}/year=${year}/month=${month}/day=${day}/hour=${hour}'
)
  • クエリ
SELECT 
  count(*)
FROM 
  transit_gateway_flow_logs_partition_projection_date
WHERE
  year=2022 and 
  dstport=22
  • ログ
GENERIC_INTERNAL_ERROR: Text '10' could not be parsed: Unable to obtain Year from TemporalAccessor: {MonthOfYear=10},ISO of type java.time.format.Parsed

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.